﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Cairo;
//using Gdk;


namespace FigureDraw
{
    public partial class Form1 : Form
    {
        public int TheBigProblem;


        List<CommonShape> shapes;
        CommonShape currentShape;
        int selectShapeIndex = -1;
        ScreenDevice screenDevice;
        Diagram diagram;

        System.Drawing.Point currentBeginPoint = System.Drawing.Point.Empty;
        System.Drawing.Point currentEndPoint = System.Drawing.Point.Empty;
        String currentLibary = "Current library: ";

        int typeDiagram = 1; //1: FlowChart, 2: DataFlow, 3: Ativity Diagram
        public Form1()
        {
            InitializeComponent();
            screenDevice = new GDIPlus(this.CreateGraphics(), new Pen(System.Drawing.Color.Red, 5),this);
            shapes = new List<CommonShape>();
            diagram = new Diagram();
            TheBigProblem = 1;
            
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                /*
                if (currentBeginPoint != System.Drawing.Point.Empty)
                {
                    System.Drawing.Point p = new System.Drawing.Point(e.X, e.Y);
                    currentEndPoint = p;
                }
                 */
                
                if (currentShape != null)
                {
                    currentEndPoint = new System.Drawing.Point(e.X, e.Y);
                    currentShape.BeginPoint = currentBeginPoint;
                    currentShape.EndPoint = currentEndPoint;

                   
                    this.Invalidate();
               }
             
            }
        }


        private void Form1_MouseUp(object sender, MouseEventArgs e)
        {
            currentEndPoint = System.Drawing.Point.Empty;
            currentBeginPoint = System.Drawing.Point.Empty;
            currentShape = null;
        }

        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            System.Drawing.Point p = new System.Drawing.Point(e.X, e.Y);
            currentBeginPoint= p;
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Draw();
        }

        private void Draw()
        {
            if (TheBigProblem == 1)
            {

                if (screenDevice.ToString().Equals("GDI Plus"))
                {

                }
                else
                {
                    Surface s = new Win32Surface(this.CreateGraphics().GetHdc());
                    Context c = new Context(s);
                    screenDevice = new CairoGraphic(s, c);

                }

                labelStatusBar.Text = currentLibary + screenDevice.ToString();

                foreach (var shape in shapes)
                    shape.DrawToDevice(this);

                diagram.DrawToDevice(this);
            }
        }


        private void buttonLine_Click(object sender, EventArgs e)
        {
            currentShape = new LineShape(screenDevice);
            currentShape.setColor(255, 0, 0);
            currentShape.setLineWidth(9);
            shapes.Add(currentShape);
        }
        
        private void buttonEcllip_Click(object sender, EventArgs e)
        {
            currentShape = new EcllipShape(screenDevice);
            currentShape.setColor(54, 117, 32);
            currentShape.setLineWidth(9);
            shapes.Add(currentShape);
        }

        private void buttonRect_Click(object sender, EventArgs e)
        {
            currentShape = new RectShape(screenDevice);
            currentShape.setColor(16, 54, 103);
            currentShape.setLineWidth(9);
            
            shapes.Add(currentShape);
        }

        private void carioToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Surface s = new Win32Surface(this.CreateGraphics().GetHdc());
            Context c = new Context(s);
            screenDevice = new CairoGraphic(s, c);
         
            this.gDIPlusToolStripMenuItem.Checked = false;
            this.carioToolStripMenuItem.Checked = true;
            ChangeLibary();
        }

        private void gDIPlusToolStripMenuItem_Click(object sender, EventArgs e)
        {
            screenDevice = new GDIPlus(this.CreateGraphics(), new Pen(System.Drawing.Color.Red, 5), this);
            this.gDIPlusToolStripMenuItem.Checked = true;
            this.carioToolStripMenuItem.Checked = false;
            
            ChangeLibary();
        }

        private void ChangeLibary()
        {
            TheBigProblem = 0;
            foreach (var s in shapes)
            {
                s.StorageDevice = screenDevice;
                
            }
            TheBigProblem = 1;
            this.Invalidate();
        }

        private void buttonStar_Click(object sender, EventArgs e)
        {
            currentShape = new StarShape(screenDevice);
            currentShape.setColor(100, 0, 75);
            currentShape.setLineWidth(9);

            shapes.Add(currentShape);
        }

        
        private void label1_Click(object sender, EventArgs e)
        {

        }

        private void buttonStart_Click(object sender, EventArgs e)
        {
            switch(typeDiagram){
                case 1:
                    currentShape = new StartSymbolFlowChart(screenDevice);
                    diagram.AddShape(currentShape);
                    break;
                case 2:
                    currentShape = new StartSymbolDataFlow(screenDevice);
                    diagram.AddShape(currentShape);
                    break;
                case 3:
                    currentShape = new StartSymbolActivity(screenDevice);
                    diagram.AddShape(currentShape);
                    break;
            }
        }

        private void fowChartToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.typeDiagram = 1;
            //currentShape = new SymbolFlowChart(screenDevice);
            this.flowChartToolStripMenuItem.Checked = true;
            this.dataFlowToolStripMenuItem.Checked = false;
            this.activityToolStripMenuItem.Checked = false;

            DiagramFactory factory = new FlowChartFactory();
            this.diagram.ConvertTo(factory);
            Draw();
        }

        private void buttonInput_Click(object sender, EventArgs e)
        {
            switch (typeDiagram)
            {
                case 1:
                    currentShape = new InputSymbolFlowChart(screenDevice);
                    diagram.AddShape(currentShape);
                    break;
                case 2:
                    currentShape = new InputSymbolDataFlow(screenDevice);
                    diagram.AddShape(currentShape);
                    break;
                case 3:
                    currentShape = new InputSymbolActivity(screenDevice);
                    diagram.AddShape(currentShape);
                    break;
            }
        }

        private void buttonProcess_Click(object sender, EventArgs e)
        {
            switch (typeDiagram)
            {
                case 1:
                    currentShape = new ProcessSymbolFlowChart(screenDevice);
                    diagram.AddShape(currentShape);
                    break;
                case 2:
                    currentShape = new ProcessSymbolDataFlow(screenDevice);
                    diagram.AddShape(currentShape);
                    break;
                case 3:
                    currentShape = new ProcessSymbolActivity(screenDevice);
                    diagram.AddShape(currentShape);
                    break;
            }
        }

        private void buttonOutput_Click(object sender, EventArgs e)
        {
            switch (typeDiagram)
            {
                case 1:
                    currentShape = new OutputSymbolFlowChart(screenDevice);
                    diagram.AddShape(currentShape);
                    break;
                case 2:
                    currentShape = new OutputSymbolDataFlow(screenDevice);
                    diagram.AddShape(currentShape);
                    break;
                case 3:
                    currentShape = new OutputSymbolActivity(screenDevice);
                    diagram.AddShape(currentShape);
                    break;
            }
        }

        private void buttonMove_Click(object sender, EventArgs e)
        {
            switch (typeDiagram)
            {
                case 1:
                    currentShape = new MoveSymbolFlowChart(screenDevice);
                    diagram.AddShape(currentShape);
                    break;
                case 2:
                    currentShape = new MoveSymbolDataFlow(screenDevice);
                    diagram.AddShape(currentShape);
                    break;
                case 3:
                    currentShape = new MoveSymbolActivity(screenDevice);
                    diagram.AddShape(currentShape);
                    break;
            }
        }

        private void buttonCondition_Click(object sender, EventArgs e)
        {
            switch (typeDiagram)
            {
                case 1:
                    currentShape = new ConditionSymbolFlowChart(screenDevice);
                    diagram.AddShape(currentShape);
                    break;
                case 2:
                    currentShape = new ConditionSymbolDataFlow(screenDevice);
                    diagram.AddShape(currentShape);
                    break;
                case 3:
                    currentShape = new ConditionSymbolActivity(screenDevice);
                    diagram.AddShape(currentShape);
                    break;
            }
        }

        private void buttonEnd_Click(object sender, EventArgs e)
        {
            switch (typeDiagram)
            {
                case 1:
                    currentShape = new EndSymbolFlowChart(screenDevice);
                    diagram.AddShape(currentShape);
                    break;
                case 2:
                    currentShape = new EndSymbolDataFlow(screenDevice);
                    diagram.AddShape(currentShape);
                    break;
                case 3:
                    currentShape = new EndSymbolActivity(screenDevice);
                    diagram.AddShape(currentShape);
                    break;
            }
        }

        private void dataFlowToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.typeDiagram = 2;
            //currentShape = new SymbolDataFlow(screenDevice);
            this.flowChartToolStripMenuItem.Checked = false;
            this.dataFlowToolStripMenuItem.Checked = true;
            this.activityToolStripMenuItem.Checked = false;

            DiagramFactory factory = new DataFlowFactory();
            this.diagram.ConvertTo(factory);
            Draw();
        }

        private void activityToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.typeDiagram = 3;
            //currentShape = new SymbolActivity(screenDevice);

            this.flowChartToolStripMenuItem.Checked = false;
            this.dataFlowToolStripMenuItem.Checked = false;
            this.activityToolStripMenuItem.Checked = true;

            DiagramFactory factory = new ActivityFactory();
            this.diagram.ConvertTo(factory);
            Draw();
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FileDevice fileDevice;
            SaveFileDialog saveFileDialog1 = new SaveFileDialog();
            saveFileDialog1.Filter = "SVG (*.svg)|*.svg|PNG (*.png)|*.png|JPEG (*.jpeg)|*.jpeg|GIF (*.gif)|*.gif";
            saveFileDialog1.Title = "Save as";
            saveFileDialog1.ShowDialog();
            if (saveFileDialog1.FileName != "")
            {

                if (screenDevice.ToString().Equals("GDI Plus"))
                {
                    Bitmap b = new Bitmap(800, 600);
                    System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(b);
                    System.Drawing.Pen p = new Pen(System.Drawing.Color.Red, 5);
                    fileDevice = new SaveByGDIPlus(g, p, b);
                    //ChangeLibary2();
                    //foreach (var shape in shapes)
                    //    shape.DrawToDevice();

                    //b.Save(saveFileDialog1.FileName, System.Drawing.Imaging.ImageFormat.Png);
                }
                else
                {
                    ImageSurface i = new ImageSurface(Cairo.Format.Argb32, 800, 600);
                    Context c = new Context(i);
                    fileDevice = new SaveByCairo(i, c);
                    //ChangeLibary2();
                    //foreach (var shape in shapes)
                    //    shape.DrawToDevice();

                    //i.WriteToPng(saveFileDialog1.FileName);

                }

                //fileDevice.save();
                //ChangeLibary();
                FileType fileType = null;
                switch (saveFileDialog1.FilterIndex)
                {
                    case 1:
                        //fileType = new SVG(saveFileDialog1.FileName, fileDevice, shapes.GetRange(0, shapes.Count));
                        fileType = new SVG();
                        break;
                    case 2:
                        //fileType = new PNG(saveFileDialog1.FileName, fileDevice, shapes.GetRange(0, shapes.Count));
                        fileType = new PNG();
                        break;
                    case 3:
                        //fileType = new JPEG(saveFileDialog1.FileName, fileDevice, shapes.GetRange(0, shapes.Count));
                        fileType = new JPEG();
                        break;
                    case 4:
                        //fileType = new GIF(saveFileDialog1.FileName, fileDevice, shapes.GetRange(0, shapes.Count));
                        fileType = new GIF();
                        break;
                }
                fileType.save(saveFileDialog1.FileName, fileDevice, shapes.GetRange(0, shapes.Count));
                ChangeLibary();
            }
        }

        private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
        {

        }

        private void Form1_MouseClick(object sender, MouseEventArgs e)
        {
            
            if (e.Button == MouseButtons.Right)
            {
                for(int i = 0; i<shapes.Count; i++)
                {
                    if (shapes[i].BeginPoint.X < e.X && e.X < shapes[i].EndPoint.X)
                        if (shapes[i].BeginPoint.Y < e.Y && e.Y < shapes[i].EndPoint.Y)
                        {
                            contextMenuStrip1.Show(e.Location);
                            this.selectShapeIndex = i;

                            if (shapes[selectShapeIndex].ToString().Contains("Border"))
                                borderToolStripMenuItem.Checked = true;
                            else
                                borderToolStripMenuItem.Checked = false;

                            if (shapes[selectShapeIndex].ToString().Contains("Shadow"))
                                shadowToolStripMenuItem.Checked = true;
                            else
                                shadowToolStripMenuItem.Checked = false;

                            if (shapes[selectShapeIndex].ToString().Contains("HighLight"))
                                highlightToolStripMenuItem.Checked = true;
                            else
                                highlightToolStripMenuItem.Checked = false;

                            return;
                        }
                }
            }
        }

        private void shadowToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (selectShapeIndex > -1 && selectShapeIndex < shapes.Count)
            {
               
                if (!shapes[selectShapeIndex].ToString().Contains("Shadow"))
                {
                    shapes[selectShapeIndex] = new Shadow(shapes[selectShapeIndex]);
                }
                else
                {
                    shapes[selectShapeIndex] = ((Shadow)(shapes[selectShapeIndex])).UnEffect();
                }
                this.Refresh();
            }
        }

        private void highlightToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (selectShapeIndex > -1 && selectShapeIndex < shapes.Count)
            {
                
                if (!shapes[selectShapeIndex].ToString().Contains("HighLight"))
                {
                    shapes[selectShapeIndex] = new HighLight(shapes[selectShapeIndex]);
                }
                else
                {
                    shapes[selectShapeIndex] = ((HighLight)(shapes[selectShapeIndex])).UnEffect();
                }
                this.Refresh();
            }
        }

       

        private void borderToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (selectShapeIndex > -1 && selectShapeIndex < shapes.Count)
            {
                if (!shapes[selectShapeIndex].ToString().Contains("Border"))
                {
                    shapes[selectShapeIndex] = new Border(shapes[selectShapeIndex]);
                }
                else
                {
                    shapes[selectShapeIndex] = ((Border)(shapes[selectShapeIndex])).UnEffect();
                }
                this.Refresh();
            }

        }


        private void buttonRefesh_Click(object sender, EventArgs e)
        {
            this.Refresh();
        }


    }
}
